#coding=utf-8
# 系统库
import json, time
import logging, traceback
import tornado.web, tornado.gen
import commlib.Constant as COMMC

from tornado import escape
from tornado.web import RequestHandler
# from torndsession.sessionhandler import SessionBaseHandler


class BaseHandler(RequestHandler):

    def initialize(self):
        # 数据库操作句柄
        self.db      = self.settings.get("database")
        # 公共数据缓存
        self.caches = self.settings.get("caches")
        # 日志模块操作句柄
        self.logger  = self.settings.get("logger")
        # 网址基地址
        self.baseUrl = self.settings.get("base_url")
        # 后台运行线程池
        self.backend = self.settings.get("thread_pool")
        # 是否需要登录的标识
        self.mustAuthed = False
        ### 模板变量赋值
        self.tplAssigns = {"title": "首页"}

        # 初始化配置类
        self.init_config_handler()
        # 子类数据初始化函数
        self.init_handler()

    def init_config_handler(self):
        pass

    def init_handler(self):
        pass

    def prepare(self):
        # 添加安全选项的http请求头
        #self.add_header("Content-Security-Policy", "default-src 'self'; script-src 'self' 'unsafe-eval'; "
        #                                           "connect-src 'self'; img-src 'self' data:; style-src 'self'; "
        #                                           "font-src 'self'; frame-src 'self'; ")
        self.add_header("X-Frame-Options", "deny")
        self.add_header("X-XSS-Protection", "1; mode=block")
        self.add_header("X-Content-Type-Options", "nosniff")
        self.add_header("x-ua-compatible:", "IE=edge,chrome=1")

        # 清空敏感头部信息
        self.clear_header("Server")

        # 判断是否是必须登录的才能进行的操作，校验是否已经认证通过的
        if self.mustAuthed: self.has_login_authed()


    def get_login_redirect_url(self):
        """ 获取登录成功后默认的跳转地址 """
        return ""

    def get_current_svrname(self):
        """ 获取当前服务名称(用于服务校验或索引) """
        return ""

    def get_current_svrole(self):
        """ 获取当前服务页面访问的最低角色权限 """
        return 19

    def has_login_authed(self):
        try:
            # 校验是否已经认证过，若没有，则重定向到错误页面
            assert type(self.current_user) is dict
            assert self.current_user.has_key('username')
        except AssertionError:
            # 若未登录的，则跳转到登录页面
            self.redirect("/login?rdurl=" + self.get_login_redirect_url())


    def subcls_static_url(self, path, include_host=None, **kwargs):
        """
        子类的获取静态文件重定义
        path 值： user/threatas/frontend/view/static/css/threatas.css
        """
        if include_host is None:
            include_host = getattr(self, "include_host", False)

        if include_host:
            base = self.request.protocol + "://" + self.request.host
        else:
            base = ""
        # 获取静态文件的版本信息
        stVersion = tornado.web.StaticFileHandler.get_version(
                    {"static_path": self.get_static_path()}, path.split('/static/', 1)[-1])

        return base + "/statics/svrs/" + path + "?v=" + stVersion


    def get_current_user(self):
        try:
            # 从session中获取已登录的信息
            user = self.session.get("userinfo")
            # 从cookie中获取已登录的信息(主要是用于[记住我]功能)
            scookie = self.get_secure_cookie("authsc")

            if (not user) and scookie:
                user = json.loads(scookie)
                if not self.set_session_userinfo(user):
                    assert False
        except:
            user = None
        # 返回当前用户信息
        return user

    def get_current_user_id(self):
        return self.current_user.get("_id", "")

    def get_current_user_role(self):
        return self.current_user.get("role", 19)

    def get_current_user_svrs(self):
        return self.current_user.get("svrs", "")

    def get_current_user_name(self):
        return self.current_user.get("username", "")

    def get_current_nick_name(self):
        return self.current_user.get("nickname", "")

    def set_session_userinfo(self, user):
        
        session = {
            "_id":      user._id,   # 这个 _id 不是字符串，若需要转换则需要用 str
            "role":     user.role,
            "svrs":     user.svrs,
            "username": user.username,
            "nickname": user.nickname
        }
        self.session.set("userinfo", session)

        # 返回已经设置的值
        return session

    def get_client_ip(self):
        # 获取请求的客户端IP
        return self.request.remote_ip

    def render(self, template_name, **kwargs):
        return super(BaseHandler, self).render(template_name, **kwargs)

    def render_end(self, template_name, **kwargs):
        super(BaseHandler, self).render(template_name, **kwargs)
        raise tornado.web.Finish()

    def redirect(self, url, permanent=False, status=None):
        super(BaseHandler, self).redirect(url, permanent, status)
        raise tornado.web.Finish()

    def write(self, sdMsg):
        super(BaseHandler, self).write(sdMsg)
        raise tornado.web.Finish()

    def _write(self, sdMsg):
        super(BaseHandler, self).write(sdMsg)
        return tornado.web.Finish()

    def write_sucs(self, msg, items=[], extra=""):
        """ 回显成功的json格式信息 """
        self.write_json(COMMC.STATUS_SUCS, msg, items, extra)

    def write_fail(self, msg, items=[], extra=""):
        """ 回显失败的json格式信息 """
        self.write_json(COMMC.STATUS_FAIL, msg, items, extra)

    def write_json(self, stats, msg, items=[], extra=""):
        """ 获取json回显结果结构体 """
        self.write({"sucs": stats, "msg": msg, 'items': items, "extra": extra})

    def custom_error(self, info, **kwargs):
        if not self._finished:
            status_code = kwargs.get("status_code", 200)
            status = kwargs.get("status", "warning")
            title = kwargs.get("title", "提示信息")
            jump = kwargs.get("jump", "#back")

            self.set_status(status_code)
            self.render("error/error.html", error_info = info,
                error_status = status, error_title = title, error_jump = jump)
        raise tornado.web.Finish()

    def write_error(self, status, **kwargs):
        """ 所有未捕获的异常，都在这里处理 """
        try:
            self.set_status(404)
            self.render("error/404.html")
        except tornado.web.Finish:
            pass

    # ajax 动态方法
    def ajax_smart_method(self, meth):
        """
        动态选择相应的ajax方法
        """
        return getattr(self, "ajax_" + meth)

    # 默认的post方法
    @tornado.web.asynchronous
    @tornado.gen.coroutine
    def post(self):
        """
        根据 相应的动态方法返回相应的信息
        """
        try:
            # 获取操作类型
            meth = self.get_body_argument('meth', default="default")
            # 动态选择函数
            yield self.ajax_smart_method(meth)()
        except tornado.web.Finish:
            pass
        except Exception as e:
            logging.debug("[POST]-[%s] 非法操作：%s" % (meth, str(e)))
            logging.debug(traceback.format_exc())
            # 返回系统错误
            self._write({"sucs": 1, "msg": "[POST]非法操作：%s" % str(e)})


    @tornado.gen.coroutine
    def safty_coroutine(self, callfunc):
        """ 用于并行处理的安全调用异步协成 """
        try:
            rest = yield callfunc
        except Exception as e:
            rest = None
            self.logger.error(str(e))
        # 返回函数调用结果
        raise tornado.gen.Return(rest)



